package com.myplans.client.presenter;

import java.util.ArrayList;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.myplans.client.Presenter;
import com.myplans.client.UserUtil;
import com.myplans.client.event.ViewPlanEvent;
import com.myplans.client.service.PlanServiceAsync;
import com.myplans.client.service.UserServiceAsync;
import com.myplans.client.util.CookieManager;
import com.myplans.client.view.BaseView;
import com.myplans.client.view.custom.PlanPanel;
import com.myplans.shared.Plan;
import com.myplans.shared.User;


public class ViewUserPresenter implements Presenter {

	public interface Display {

		public Widget asWidget();
		
		public FlowPanel getPlansPanel();
		
		public Label getUserName();
		
		public Button getSubscribe();
		
		public void setPicture(Image picture);
		
	}

	private HandlerManager eventBus;
	private Display display;
	private UserServiceAsync userServiceAsync;
	private PlanServiceAsync planService;
	private User user;

	public ViewUserPresenter(HandlerManager eventBus, Display display) {
		this.eventBus = eventBus;
		this.display = display;
		this.bind();
	}

	@SuppressWarnings("deprecation")
	public void go(HasWidgets container) {
		((BaseView)container).getCentralPanel().clear();
		((BaseView)container).getCentralPanel().add(display.asWidget());
		if (CookieManager.getSessionId() != null) {
			display.getSubscribe().setVisible(true);
			userServiceAsync.getSubscriptionsForUser(UserUtil.user, new AsyncCallback<ArrayList<User>>() {
				
				@Override
				public void onSuccess(ArrayList<User> result) {
					if (result.contains(user)) {
						display.getSubscribe().setText("Unsubscribe");
					} else {
						display.getSubscribe().setText("Subscribe");
					}
				}
				
				@Override
				public void onFailure(Throwable caught) {
					Window.alert("Could not get subscription for user");
				}
			});
		}
		
		display.getUserName().setText(user.getName());
		if (user.getPicture() != null) {
			Image image = new Image(user.getPicture());
			display.setPicture(image);
		}
		
		userServiceAsync.getPlansForUser(UserUtil.user, new AsyncCallback<ArrayList<Plan>>() {
			
			@Override
			public void onSuccess(ArrayList<Plan> result) {
				final ArrayList<Plan> userPlans = result;
				userServiceAsync.getPlansForUser(user, new AsyncCallback<ArrayList<Plan>>() {
					
					@Override
					public void onSuccess(ArrayList<Plan> result) {
						for (Plan plan : result) {
							final PlanPanel panel = new PlanPanel(plan, userPlans.contains(plan));
							display.getPlansPanel().add(panel);
							panel.getTitleLabel().addClickHandler(new ClickHandler() {
								
								@Override
								public void onClick(ClickEvent event) {
									eventBus.fireEvent(new ViewPlanEvent(panel.getPlan()));
								}
							});
							panel.getAttendButton().addClickHandler(new ClickHandler() {
								
								@Override
								public void onClick(ClickEvent event) {
									if (panel.isAttending() == true) {
										userServiceAsync.deletePlanForUser(panel.getPlan(), UserUtil.user
												, new AsyncCallback<User>() {
												
													@Override
													public void onSuccess(User result) {
														panel.setAttending(false);
													}
												
													@Override
													public void onFailure(Throwable caught) {
														Window.alert("Could not de-attend this plan");
													}
										});
									} else {
										userServiceAsync.createPlanForUser(panel.getPlan(), UserUtil.user
												, new AsyncCallback<User>() {
												
													@Override
													public void onSuccess(User result) {
														panel.setAttending(true);
													}
												
													@Override
													public void onFailure(Throwable caught) {
														Window.alert("Could not attend this plan");
													}
										});
									}
								}
							});
						}
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Could not get plans for user");
			}
			});
		
			}

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}
		});
	}

	private void bind() {
		display.getSubscribe().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				if ("Subscribe".equals(display.getSubscribe().getText())) {
					userServiceAsync.createSubscriptionForUser(user, UserUtil.user, new AsyncCallback<User>() {
						
						@Override
						public void onSuccess(User result) {
							display.getSubscribe().setText("Unsubscribe");
						}
						
						@Override
						public void onFailure(Throwable caught) {
							Window.alert("Could not create subscription for user");
						}
					});
				} else {
					userServiceAsync.deleteSubscriptionForUser(user, UserUtil.user, new AsyncCallback<User>() {
						
						@Override
						public void onSuccess(User result) {
							display.getSubscribe().setText("Subscribe");
						}
						
						@Override
						public void onFailure(Throwable caught) {
							Window.alert("Could not delete subscription for user");
						}
					});
				}
			}
		});
	}

	public void setUsersService(UserServiceAsync userServiceAsync) {
		this.userServiceAsync = userServiceAsync;
	}

	public void setPlanService(PlanServiceAsync planServiceAsync) {
		this.planService = planServiceAsync;
	}

	public void setUser(User user) {
		this.user = user;
	}

}
